/**
 * This software is copyrighted by Bosch Connected Devices and Solutions GmbH, 2016.
 * The use of this software is subject to the XDK SDK EULA
 */

/* system header files */
#include "BCDS_Basics.h"

/* own header files */
#include "Accelerometer.h"
#include "BCDS_Accelerometer.h"

/* additional interface header files */
#include <FreeRTOS.h>
#include <timers.h>
#include "BCDS_Bmi160Utils.h"
#include "BCDS_Bma280Utils.h"
#include <bmi160.h>
#include <bma2x2.h>

/* local variables ********************************************************** */

/*  This variable is used to store the current value of range, it will be
 *  used to calculate the value of g from LSB. Since the default value is 2g
 *  it has been defined as 2
 */
static uint8_t bmaRangeValue = BMA2X2_SUPPORT_2G_RANGE;
static uint8_t bmiRangeValue = BMI160_SUPPORT_2G_RANGE;

/** function pointer holding handle to application's deferred routine */
static PendedFunction_t bmaDeferredCallbackChannel1Ptr = NULL;
static PendedFunction_t bmaDeferredCallbackChannel2Ptr = NULL;

/* global variables ********************************************************* */


static const uint8_t bwLookUpTable[ACCELEROMETER_BANDWIDTH_OUT_OF_RANGE] =
{
    UINT8_C(BMA2x2_BW_7_81HZ),
    UINT8_C(BMA2x2_BW_15_63HZ),
    UINT8_C(BMA2x2_BW_31_25HZ),
    UINT8_C(BMA2x2_BW_62_50HZ),
    UINT8_C(BMA2x2_BW_125HZ),
    UINT8_C(BMA2x2_BW_250HZ),
    UINT8_C(BMA2x2_BW_500HZ),
    UINT8_C(BMI160_ACCEL_OUTPUT_DATA_RATE_0_78HZ),
    UINT8_C(BMI160_ACCEL_OUTPUT_DATA_RATE_1_56HZ),
    UINT8_C(BMI160_ACCEL_OUTPUT_DATA_RATE_3_12HZ),
    UINT8_C(BMI160_ACCEL_OUTPUT_DATA_RATE_6_25HZ),
    UINT8_C(BMI160_ACCEL_OUTPUT_DATA_RATE_12_5HZ),
    UINT8_C(BMI160_ACCEL_OUTPUT_DATA_RATE_25HZ),
    UINT8_C(BMI160_ACCEL_OUTPUT_DATA_RATE_50HZ),
    UINT8_C(BMI160_ACCEL_OUTPUT_DATA_RATE_100HZ),
    UINT8_C(BMI160_ACCEL_OUTPUT_DATA_RATE_200HZ),
    UINT8_C(BMI160_ACCEL_OUTPUT_DATA_RATE_400HZ)
};

static const uint8_t modeLookUpTable[ACCELEROMETER_POWERMODE_OUT_OF_RANGE] =
{
    UINT8_C(BMA2x2_MODE_NORMAL),
    UINT8_C(BMA2x2_MODE_LOWPOWER1),
    UINT8_C(BMA2x2_MODE_SUSPEND),
    UINT8_C(BMA2x2_MODE_DEEP_SUSPEND),
    UINT8_C(BMA2x2_MODE_LOWPOWER2),
    UINT8_C(BMA2x2_MODE_STANDBY),
    UINT8_C(ACCEL_MODE_NORMAL),
    UINT8_C(ACCEL_LOWPOWER),
    UINT8_C(ACCEL_SUSPEND),
};

static const uint8_t rangeLookUpTable[ACCELEROMETER_RANGE_OUT_OF_BOUND] =
{
    UINT8_C(BMA2x2_RANGE_2G),
    UINT8_C(BMA2x2_RANGE_4G),
    UINT8_C(BMA2x2_RANGE_8G),
    UINT8_C(BMA2x2_RANGE_16G),
    UINT8_C(BMI160_ACCEL_RANGE_2G),
    UINT8_C(BMI160_ACCEL_RANGE_4G),
    UINT8_C(BMI160_ACCEL_RANGE_8G),
    UINT8_C(BMI160_ACCEL_RANGE_16G)

};
static const uint8_t sleepDurationLookUpTable[ACCELEROMETER_SLEEP_DURATION_OUT_OF_RANGE] =
{
    UINT8_C(BMA2x2_SLEEP_DURN_0_5MS),
    UINT8_C(BMA2x2_SLEEP_DURN_1MS),
    UINT8_C(BMA2x2_SLEEP_DURN_2MS),
    UINT8_C(BMA2x2_SLEEP_DURN_4MS),
    UINT8_C(BMA2x2_SLEEP_DURN_6MS),
    UINT8_C(BMA2x2_SLEEP_DURN_10MS),
    UINT8_C(BMA2x2_SLEEP_DURN_25MS),
    UINT8_C(BMA2x2_SLEEP_DURN_50MS),
    UINT8_C(BMA2x2_SLEEP_DURN_100MS),
    UINT8_C(BMA2x2_SLEEP_DURN_500MS),
    UINT8_C(BMA2x2_SLEEP_DURN_1S)
};

static const uint8_t rangeValueLookUpTable[ACCELEROMETER_RANGE_OUT_OF_BOUND] = {
    UINT8_C(BMA2X2_SUPPORT_2G_RANGE),
    UINT8_C(BMA2X2_SUPPORT_4G_RANGE),
    UINT8_C(BMA2X2_SUPPORT_8G_RANGE),
    UINT8_C(BMA2X2_SUPPORT_16G_RANGE),
    UINT8_C(BMI160_SUPPORT_2G_RANGE),
    UINT8_C(BMI160_SUPPORT_4G_RANGE),
    UINT8_C(BMI160_SUPPORT_8G_RANGE),
    UINT8_C(BMI160_SUPPORT_16G_RANGE)
};

static const uint8_t getmodeLookUpTable[ACCELEROMETER_POWERMODE_OUT_OF_RANGE] =
{
    UINT8_C(BMA2x2_MODE_NORMAL),
    UINT8_C(BMA2x2_MODE_LOWPOWER1),
    UINT8_C(BMA2x2_MODE_SUSPEND),
    UINT8_C(BMA2x2_MODE_DEEP_SUSPEND),
    UINT8_C(BMA2x2_MODE_LOWPOWER2),
    UINT8_C(BMA2x2_MODE_STANDBY),
    UINT8_C(BMI160_ACCEL_NORMAL_MODE),
    UINT8_C(BMI160_ACCEL_LOW_POWER),
    UINT8_C(BMI160_ACCEL_SUSPEND),
};

/**
 * @brief BMA280 deferred callback function for channel1 which is responsible to call application's
 * deferred routine.
 *
 * @param [in]   interruptDataPointer pointer for future extension.
 *
 * @param [in]   interruptData input data from ISR.
 */
static void bmaDeferredChannel1Callback(void *interruptDataPointer, uint32_t interruptData)
{
    /* call application's deferred callback */
    if (NULL != bmaDeferredCallbackChannel1Ptr)
    {
        bmaDeferredCallbackChannel1Ptr(interruptDataPointer, interruptData);
    }
}

/**
 * @brief BMA280 deferred callback function for channel2 which is responsible to call application's
 * deferred routine.
 *
 * @param [in]   interruptDataPointer pointer for future extension.
 *
 * @param [in]   interruptData input data from ISR.
 *
 */
static void bmaDeferredChannel2Callback(void *interruptDataPointer, uint32_t interruptData)
{
    /* call application's deferred callback */
    if (NULL != bmaDeferredCallbackChannel2Ptr)
    {
        bmaDeferredCallbackChannel2Ptr(interruptDataPointer, interruptData);
    }
}

/**
 * @brief BMA280 driver callback function for channel1 that will be called during ISR, when deferred
 * application callback is registered.  This is responsible to defer the context.
 */
static void bmaChannel1IsrCallback(void)
{
    int8_t returnValue = INT32_C(-1);

    /* pending to deferred procedure call to lower the context and to call application's deferred callback */
    portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
    if (xTimerPendFunctionCallFromISR(bmaDeferredChannel1Callback, NULL, UINT8_C(0), &xHigherPriorityTaskWoken) == pdPASS )
    {
        returnValue = INT32_C(0);
        portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
    }
    if (INT32_C(0) != returnValue)
    {
        Retcode_raiseError(returnValue);
    }
}

/**
 * @brief BMA280 driver callback function for channel2 that will be called during ISR, when deferred
 * application callback is registered.  This is responsible to defer the context.
 */
static void bmaChannel2IsrCallback(void)
{
    int8_t returnValue = INT32_C(-1);

    /* pending to deferred procedure call to lower the context and to call application's deferred callback */
    portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
    if (xTimerPendFunctionCallFromISR(bmaDeferredChannel2Callback, NULL, UINT8_C(0), &xHigherPriorityTaskWoken) == pdPASS )
    {
        returnValue = INT32_C(0);
        portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
    }
    if (INT32_C(0) != returnValue)
    {
        Retcode_raiseError(returnValue);
    }
}

/* inline functions */
static int8_t mappingEnumForGetFunctions(uint8_t start, uint8_t end, uint8_t getValueToBeTransalated, const uint8_t * lookUpTablePtr)
{
    uint8_t i = UINT8_C(0);
    int8_t apiReturnValue = GET_MAPPING_ERROR;

    for (i = start; i <= end; i++)
    {
        if (getValueToBeTransalated == *(lookUpTablePtr + i))
        {
            apiReturnValue = i;
            break;
        }
    }

    return (apiReturnValue);
}

/* local functions */
static Retcode_T bma2x2LibErrorMapping(BMA2x2_RETURN_FUNCTION_TYPE BMA2X2_libReturn)
{
    Retcode_T returnValue = (Retcode_T) RETCODE_FAILURE;

    if (BMA2X2_libReturn == (BMA2x2_RETURN_FUNCTION_TYPE) UINT8_C(0))
    {
        returnValue = (Retcode_T) RETCODE_SUCCESS;
    }
    else if (BMA2X2_libReturn == E_BMA2x2_NULL_PTR)
    {
        returnValue = (Retcode_T) RETCODE_INVALID_PARAM;
    }
    else
    {
        returnValue = (Retcode_T) RETCODE_FAILURE;
    }

    return (returnValue);
}

static Retcode_T bmi160LibErrorMapping(BMI160_RETURN_FUNCTION_TYPE BMI160_libReturn)
{
    Retcode_T returnValue = (Retcode_T) RETCODE_FAILURE;

    if (BMI160_libReturn == SUCCESS)
    {
        returnValue = (Retcode_T) RETCODE_SUCCESS;
    }
    else if (BMI160_libReturn == E_BMI160_NULL_PTR)
    {
        returnValue = (Retcode_T) RETCODE_INVALID_PARAM;
    }
    else
    {
        returnValue = (Retcode_T) RETCODE_FAILURE;
    }

    return (returnValue);
}

/* API documentation is in public interface header file 'BCDS_Accelerometer.h' */
Retcode_T Accelerometer_init(Accelerometer_HandlePtr_T handle)
{
    Retcode_T apiReturnValue = (Retcode_T) RETCODE_FAILURE;

    if ((NULL == handle) || (NULL == handle->SensorPtr))
    {
        return (RETCODE(RETCODE_SEVERITY_FATAL, (uint32_t) RETCODE_INVALID_PARAM));
    }
    if (true == handle->SensorInformation.initializationStatus)
    {
        return (RETCODE_OK);
    }

    switch (handle->SensorInformation.sensorID)
    {
    case ACCELEROMETER_BMA280:
        apiReturnValue = Bma280Utils_initialize((Bma280Utils_InfoPtr_T) handle->SensorPtr);
        if (RETCODE_OK == apiReturnValue)
        {
            handle->SensorInformation.initializationStatus = true;
        }
        else
        {
            handle->SensorInformation.initializationStatus = false;
        }
        break;
    case ACCELEROMETER_BMI160:
        apiReturnValue = Bmi160Utils_initialize((Bmi160Utils_InfoPtr_T) handle->SensorPtr);
        if (RETCODE_OK == apiReturnValue)
        {
            handle->SensorInformation.initializationStatus = INIT_DONE;
        }
        else
        {
            handle->SensorInformation.initializationStatus = INIT_NOT_DONE;
        }
        break;

    default:
        apiReturnValue = (Retcode_T) RETCODE_INVALID_PARAM;
        break;
    }

    if ((RETCODE_OK != apiReturnValue) && (Retcode_getPackage(apiReturnValue) == PACKAGE_ID_DEFAULT))
    {
        apiReturnValue = RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) apiReturnValue);
    }

    return (apiReturnValue);
}

/* API documentation is in public interface header file 'BCDS_Accelerometer.h' */
Retcode_T Accelerometer_setBandwidth(Accelerometer_HandlePtr_T handle, Accelerometer_Bandwidth_T bandwidth)
{
    Retcode_T apiReturnValue = (Retcode_T) RETCODE_FAILURE;
    BMA2x2_RETURN_FUNCTION_TYPE libBma280ReturnValue = E_OUT_OF_RANGE;
    BMI160_RETURN_FUNCTION_TYPE libBmi160ReturnValue = E_BMI160_OUT_OF_RANGE;

    if ((NULL == handle) || (NULL == handle->SensorPtr))
    {
        return (RETCODE(RETCODE_SEVERITY_FATAL, (uint32_t) RETCODE_INVALID_PARAM));
    }
    if ((bandwidth >= ACCELEROMETER_BANDWIDTH_OUT_OF_RANGE))
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) RETCODE_INVALID_PARAM));
    }
    if (false == (handle->SensorInformation.initializationStatus))
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) RETCODE_UNINITIALIZED));
    }

    switch (handle->SensorInformation.sensorID)
    {
    case ACCELEROMETER_BMA280:
        if (bandwidth > ACCELEROMETER_BMA280_BANDWIDTH_500HZ)
        {
            apiReturnValue = (Retcode_T) RETCODE_NOT_SUPPORTED;

        }
        else
        {
            libBma280ReturnValue = bma2x2_set_high_bw(BMA2X2_FILTERED_LOW_BANDWIDTH);
            if (UINT8_C(0) == libBma280ReturnValue)
            {


                libBma280ReturnValue = bma2x2_set_bw(bwLookUpTable[bandwidth]);


            }
            apiReturnValue = bma2x2LibErrorMapping(libBma280ReturnValue);
        }
        break;
    case ACCELEROMETER_BMI160:

        if (bandwidth < ACCELEROMETER_BMI160_BANDWIDTH_0_39HZ)
        {
            apiReturnValue = (Retcode_T) RETCODE_NOT_SUPPORTED;
        }
        else
        {


            libBmi160ReturnValue = bmi160_set_accel_under_sampling_parameter(ENABLE_UNDERSAMPLING);
            if (SUCCESS == libBmi160ReturnValue)
            {
                libBmi160ReturnValue = bmi160_set_accel_output_data_rate(bwLookUpTable[bandwidth],BMI160_ACCEL_RES_AVG2);
            }
            if (SUCCESS == libBmi160ReturnValue)
            {
                libBmi160ReturnValue = bmi160_set_accel_bw(BMI160_ACCEL_NORMAL_AVG4);
            }


            apiReturnValue = bmi160LibErrorMapping(libBmi160ReturnValue);
        }
        break;
    default:
        apiReturnValue = (Retcode_T) RETCODE_INVALID_PARAM;
        break;
    }

    if ((RETCODE_OK != apiReturnValue) && (Retcode_getPackage(apiReturnValue) == PACKAGE_ID_DEFAULT))
    {
        apiReturnValue = RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) apiReturnValue);
    }

    return (apiReturnValue);
}

/* API documentation is in public interface header file 'BCDS_Accelerometer.h' */
Retcode_T Accelerometer_getBandwidth(Accelerometer_HandlePtr_T handle, Accelerometer_BandwidthPtr_T bandwidth)
{
    int8_t tempretVal = GET_MAPPING_ERROR;
    Retcode_T apiReturnValue = (Retcode_T) RETCODE_FAILURE;
    BMA2x2_RETURN_FUNCTION_TYPE libBma280ReturnValue = E_OUT_OF_RANGE;
    BMI160_RETURN_FUNCTION_TYPE libBmi160ReturnValue = E_BMI160_OUT_OF_RANGE;
    Accelerometer_Bandwidth_T tempBandwidth = ACCELEROMETER_BANDWIDTH_OUT_OF_RANGE;

    if ((NULL == handle) || ( NULL == bandwidth))
    {
        return (RETCODE(RETCODE_SEVERITY_FATAL, (uint32_t) RETCODE_INVALID_PARAM));
    }
    if (handle->SensorInformation.initializationStatus == false)
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) RETCODE_UNINITIALIZED));
    }

    switch (handle->SensorInformation.sensorID)
    {
    case ACCELEROMETER_BMA280:



        libBma280ReturnValue = bma2x2_get_bw((uint8_t *) bandwidth);

        apiReturnValue = bma2x2LibErrorMapping(libBma280ReturnValue);
        if (RETCODE_OK == apiReturnValue)
        {
            tempBandwidth = *bandwidth;
            tempretVal = mappingEnumForGetFunctions((uint8_t) ACCELEROMETER_BMA280_BANDWIDTH_7_81HZ, (uint8_t) ACCELEROMETER_BMA280_BANDWIDTH_500HZ, (uint8_t) tempBandwidth, bwLookUpTable);

            if (GET_MAPPING_ERROR != tempretVal)
            {
                *bandwidth = (Accelerometer_Bandwidth_T) tempretVal;
            }
            else
            {
                apiReturnValue = (Retcode_T) RETCODE_NOT_SUPPORTED;
            }

        }
        break;
    case ACCELEROMETER_BMI160:


        libBmi160ReturnValue = bmi160_get_accel_output_data_rate((uint8_t *) bandwidth);


        apiReturnValue = bmi160LibErrorMapping(libBmi160ReturnValue);
        if (RETCODE_OK == apiReturnValue)
        {
            tempBandwidth = *bandwidth;
            tempretVal = mappingEnumForGetFunctions((uint8_t) ACCELEROMETER_BMI160_BANDWIDTH_0_39HZ, (uint8_t) ACCELEROMETER_BMI160_BANDWIDTH_200HZ, (uint8_t) tempBandwidth, bwLookUpTable);
            if (GET_MAPPING_ERROR != tempretVal)
            {
                *bandwidth = (Accelerometer_Bandwidth_T) tempretVal;
            }
            else
            {
                apiReturnValue = (Retcode_T) RETCODE_NOT_SUPPORTED;
            }
        }
        break;
    default:
        apiReturnValue = (Retcode_T) RETCODE_INVALID_PARAM;
        break;
    }

    if ((RETCODE_OK != apiReturnValue) && (Retcode_getPackage(apiReturnValue) == PACKAGE_ID_DEFAULT))
    {
        apiReturnValue = RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) apiReturnValue);
    }

    return (apiReturnValue);
}

/* API documentation is in public interface header file 'BCDS_Accelerometer.h' */
Retcode_T Accelerometer_setRange(Accelerometer_HandlePtr_T handle, Accelerometer_Range_T range)
{
    Retcode_T apiReturnValue = (Retcode_T) RETCODE_FAILURE;
    BMA2x2_RETURN_FUNCTION_TYPE libBma280ReturnValue = E_OUT_OF_RANGE;
    BMI160_RETURN_FUNCTION_TYPE libBmi160ReturnValue = E_BMI160_OUT_OF_RANGE;

    if (NULL == handle)
    {
        return (RETCODE(RETCODE_SEVERITY_FATAL, (uint32_t) RETCODE_INVALID_PARAM));
    }
    if (range >= ACCELEROMETER_RANGE_OUT_OF_BOUND)
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) RETCODE_INVALID_PARAM));
    }
    if (handle->SensorInformation.initializationStatus == false)
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) RETCODE_UNINITIALIZED));
    }

    switch (handle->SensorInformation.sensorID)
    {
    case ACCELEROMETER_BMA280:
        if (range > ACCELEROMETER_BMA280_RANGE_16G)
        {
            apiReturnValue = (Retcode_T) RETCODE_NOT_SUPPORTED;
        }
        else
        {
            libBma280ReturnValue = bma2x2_set_range(rangeLookUpTable[range]);
            if (UINT8_C(0) == libBma280ReturnValue)
            {
                bmaRangeValue = rangeValueLookUpTable[range];
            }
            apiReturnValue = bma2x2LibErrorMapping(libBma280ReturnValue);
        }
        break;
    case ACCELEROMETER_BMI160:
        if (range < ACCELEROMETER_BMI160_RANGE_2G)
        {
            apiReturnValue = (Retcode_T) RETCODE_NOT_SUPPORTED;
        }
        else
        {


            libBmi160ReturnValue = bmi160_set_accel_range(rangeLookUpTable[range]);


            if (SUCCESS == libBmi160ReturnValue)
            {
                bmiRangeValue = rangeValueLookUpTable[range];
            }
            apiReturnValue = bmi160LibErrorMapping(libBmi160ReturnValue);
        }
        break;
    default:
        apiReturnValue = (Retcode_T) RETCODE_INVALID_PARAM;
        break;
    }

    if ((RETCODE_OK != apiReturnValue) && (Retcode_getPackage(apiReturnValue) == PACKAGE_ID_DEFAULT))
    {
        apiReturnValue = RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) apiReturnValue);
    }

    return (apiReturnValue);
}

/* API documentation is in public interface header file 'BCDS_Accelerometer.h' */
Retcode_T Accelerometer_getRange(Accelerometer_HandlePtr_T handle, Accelerometer_RangePtr_T range)
{
    int8_t tempretVal = GET_MAPPING_ERROR;
    BMA2x2_RETURN_FUNCTION_TYPE libBma280ReturnValue = E_OUT_OF_RANGE;
    BMI160_RETURN_FUNCTION_TYPE libBmi160ReturnValue = E_BMI160_OUT_OF_RANGE;
    Retcode_T apiReturnValue = (Retcode_T) RETCODE_FAILURE;

    if (NULL == handle || NULL == range)
    {
        return (RETCODE(RETCODE_SEVERITY_FATAL, (uint32_t) RETCODE_INVALID_PARAM));
    }
    if (handle->SensorInformation.initializationStatus == false)
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) RETCODE_UNINITIALIZED));
    }

    switch (handle->SensorInformation.sensorID)
    {
    case ACCELEROMETER_BMA280:
        libBma280ReturnValue = bma2x2_get_range((uint8_t *) range);
        apiReturnValue = bma2x2LibErrorMapping(libBma280ReturnValue);
        if (RETCODE_OK == apiReturnValue)
        {
            tempretVal = mappingEnumForGetFunctions((uint8_t) ACCELEROMETER_BMA280_RANGE_2G, (uint8_t) ACCELEROMETER_BMA280_RANGE_16G, (uint8_t) *range, rangeLookUpTable);
            if (GET_MAPPING_ERROR != tempretVal)
            {
                *range = (Accelerometer_Range_T) tempretVal;
            }
            else
            {
                apiReturnValue = (Retcode_T) RETCODE_NOT_SUPPORTED;
            }
        }
        break;
    case ACCELEROMETER_BMI160:


        libBmi160ReturnValue = bmi160_get_accel_range((uint8_t *) range);

        apiReturnValue = bmi160LibErrorMapping(libBmi160ReturnValue);
        if (RETCODE_OK == apiReturnValue)
        {
            tempretVal = mappingEnumForGetFunctions((uint8_t) ACCELEROMETER_BMI160_RANGE_2G, (uint8_t) ACCELEROMETER_BMI160_RANGE_16G, (uint8_t) *range, rangeLookUpTable);
            if (GET_MAPPING_ERROR != tempretVal)
            {
                *range = (Accelerometer_Range_T) tempretVal;
            }
            else
            {
                apiReturnValue = (Retcode_T) RETCODE_NOT_SUPPORTED;
            }
        }
        break;

    default:
        apiReturnValue = (Retcode_T) RETCODE_INVALID_PARAM;
        break;
    }

    if ((RETCODE_OK != apiReturnValue) && (Retcode_getPackage(apiReturnValue) == PACKAGE_ID_DEFAULT))
    {
        apiReturnValue = RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) apiReturnValue);
    }

    return (apiReturnValue);
}

/* API documentation is in public interface header file 'BCDS_Accelerometer.h' */
Retcode_T Accelerometer_setSleepDuration(Accelerometer_HandlePtr_T handle, Accelerometer_SleepDuration_T lowPowerModeSleepDuration)
{
    Retcode_T apiReturnValue = (Retcode_T) RETCODE_FAILURE;
    BMA2x2_RETURN_FUNCTION_TYPE libBma280ReturnValue = E_OUT_OF_RANGE;

    if ((NULL == handle) || (NULL == handle->SensorPtr))
    {
        return (RETCODE(RETCODE_SEVERITY_FATAL, (uint32_t) RETCODE_INVALID_PARAM));
    }
    if (lowPowerModeSleepDuration >= ACCELEROMETER_SLEEP_DURATION_OUT_OF_RANGE)
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) RETCODE_INVALID_PARAM));
    }
    if (false == handle->SensorInformation.initializationStatus)
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) RETCODE_UNINITIALIZED));
    }

    switch (handle->SensorInformation.sensorID)
    {
    case ACCELEROMETER_BMA280:



        libBma280ReturnValue = bma2x2_set_sleep_durn(sleepDurationLookUpTable[lowPowerModeSleepDuration]);

        apiReturnValue = bma2x2LibErrorMapping(libBma280ReturnValue);
        break;
    case ACCELEROMETER_BMI160:
        apiReturnValue = (Retcode_T) RETCODE_NOT_SUPPORTED;
        break;
    default:
        apiReturnValue = (Retcode_T) RETCODE_INVALID_PARAM;
        break;
    }

    if ((RETCODE_OK != apiReturnValue) && (Retcode_getPackage(apiReturnValue) == PACKAGE_ID_DEFAULT))
    {
        apiReturnValue = RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) apiReturnValue);
    }

    return (apiReturnValue);
}

/* API documentation is in public interface header file 'BCDS_Accelerometer.h' */
Retcode_T Accelerometer_getSleepDuration(Accelerometer_HandlePtr_T handle, Accelerometer_SleepDurationPtr_T lowPowerModeSleepDuration)
{
    int8_t tempretVal = GET_MAPPING_ERROR;
    Retcode_T apiReturnValue = (Retcode_T) RETCODE_FAILURE;
    BMA2x2_RETURN_FUNCTION_TYPE libBma280ReturnValue = E_OUT_OF_RANGE;
    Accelerometer_SleepDuration_T sleepDuration = ACCELEROMETER_SLEEP_DURATION_OUT_OF_RANGE;

    if ((NULL == handle) || (NULL == lowPowerModeSleepDuration))
    {
        return (RETCODE(RETCODE_SEVERITY_FATAL, (uint32_t) RETCODE_INVALID_PARAM));
    }
    if (false == handle->SensorInformation.initializationStatus)
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) RETCODE_UNINITIALIZED));
    }

    switch (handle->SensorInformation.sensorID)
    {
    case ACCELEROMETER_BMA280:



        libBma280ReturnValue = bma2x2_get_sleep_durn((uint8_t *) lowPowerModeSleepDuration);


        apiReturnValue = bma2x2LibErrorMapping(libBma280ReturnValue);
        if (RETCODE_OK == apiReturnValue)
        {
            sleepDuration = *lowPowerModeSleepDuration;

            tempretVal = mappingEnumForGetFunctions((uint8_t) ACCELEROMETER_BMA280_SLEEP_DURATION_0_5MS, (uint8_t) ACCELEROMETER_BMA280_SLEEP_DURATION_1S, (uint8_t) sleepDuration, sleepDurationLookUpTable);
            if (GET_MAPPING_ERROR != tempretVal)
            {
                *lowPowerModeSleepDuration = (Accelerometer_SleepDuration_T) tempretVal;
            }
            else
            {
                apiReturnValue = (Retcode_T) RETCODE_NOT_SUPPORTED;
            }
        }
        break;
    case ACCELEROMETER_BMI160:
        apiReturnValue = (Retcode_T) RETCODE_NOT_SUPPORTED;
        break;
    default:
        apiReturnValue = (Retcode_T) RETCODE_INVALID_PARAM;
        break;
    }

    if ((RETCODE_OK != apiReturnValue) && (Retcode_getPackage(apiReturnValue) == PACKAGE_ID_DEFAULT))
    {
        apiReturnValue = RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) apiReturnValue);
    }

    return (apiReturnValue);
}

/* API documentation is in public interface header file 'BCDS_Accelerometer.h' */
Retcode_T Accelerometer_setMode(Accelerometer_HandlePtr_T handle, Accelerometer_Powermode_T powermode)
{
    Retcode_T apiReturnValue = (Retcode_T) RETCODE_FAILURE;
    BMA2x2_RETURN_FUNCTION_TYPE libBma280ReturnValue = E_OUT_OF_RANGE;
    BMI160_RETURN_FUNCTION_TYPE libBmi160ReturnValue = E_BMI160_OUT_OF_RANGE;

    if ((NULL == handle) || (NULL == handle->SensorPtr))
    {
        return (RETCODE(RETCODE_SEVERITY_FATAL, (uint32_t) RETCODE_INVALID_PARAM));
    }
    if (powermode >= ACCELEROMETER_POWERMODE_OUT_OF_RANGE)
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) RETCODE_INVALID_PARAM));
    }
    if (false == handle->SensorInformation.initializationStatus)
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) RETCODE_UNINITIALIZED));
    }

    switch (handle->SensorInformation.sensorID)
    {
    case ACCELEROMETER_BMA280:
        if (powermode > ACCELEROMETER_BMA280_POWERMODE_STANDBY)
        {
            apiReturnValue = (Retcode_T) RETCODE_NOT_SUPPORTED;
        }
        else
        {


            libBma280ReturnValue = bma2x2_set_power_mode(modeLookUpTable[powermode]);

            apiReturnValue = bma2x2LibErrorMapping(libBma280ReturnValue);
        }
        break;
    case ACCELEROMETER_BMI160:
        if ((powermode < ACCELEROMETER_BMI160_POWERMODE_NORMAL) || (powermode > ACCELEROMETER_BMI160_POWERMODE_SUSPEND))
        {
            apiReturnValue = (Retcode_T) RETCODE_NOT_SUPPORTED;
        }
        else
        {
            libBmi160ReturnValue = bmi160_set_command_register(modeLookUpTable[powermode]);
            apiReturnValue = bmi160LibErrorMapping(libBmi160ReturnValue);
        }
        break;
    default:
        apiReturnValue = (Retcode_T) RETCODE_INVALID_PARAM;
        break;
    }

    if ((RETCODE_OK != apiReturnValue) && (Retcode_getPackage(apiReturnValue) == PACKAGE_ID_DEFAULT))
    {
        apiReturnValue = RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) apiReturnValue);
    }

    return (apiReturnValue);
}

/* API documentation is in public interface header file 'BCDS_Accelerometer.h' */
Retcode_T Accelerometer_getMode(Accelerometer_HandlePtr_T handle, Accelerometer_PowermodePtr_T powermode)
{
    int8_t tempretVal = GET_MAPPING_ERROR;
    Retcode_T apiReturnValue = (Retcode_T) RETCODE_FAILURE;
    BMA2x2_RETURN_FUNCTION_TYPE libBma280ReturnValue = E_OUT_OF_RANGE;
    BMI160_RETURN_FUNCTION_TYPE libBmi160ReturnValue = E_BMI160_OUT_OF_RANGE;

    if ((NULL == handle) || (NULL == powermode))
    {
        return (RETCODE(RETCODE_SEVERITY_FATAL, (uint32_t) RETCODE_INVALID_PARAM));
    }
    if (INIT_NOT_DONE == handle->SensorInformation.initializationStatus)
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) RETCODE_UNINITIALIZED));
    }

    switch (handle->SensorInformation.sensorID)
    {
    case ACCELEROMETER_BMA280:



        libBma280ReturnValue = bma2x2_get_power_mode((uint8_t *) powermode);


        apiReturnValue = bma2x2LibErrorMapping(libBma280ReturnValue);
        if (RETCODE_OK == apiReturnValue)
        {
            tempretVal = mappingEnumForGetFunctions((uint8_t) ACCELEROMETER_BMA280_POWERMODE_NORMAL, (uint8_t) ACCELEROMETER_BMA280_POWERMODE_STANDBY, (uint8_t) *powermode, modeLookUpTable);
            if (GET_MAPPING_ERROR != tempretVal)
            {
                *powermode = (Accelerometer_Powermode_T) tempretVal;
            }
            else
            {
                apiReturnValue = (Retcode_T) RETCODE_NOT_SUPPORTED;
            }
        }
        break;
    case ACCELEROMETER_BMI160:


        libBmi160ReturnValue = bmi160_get_accel_power_mode_stat((uint8_t *) powermode);

        apiReturnValue = bmi160LibErrorMapping(libBmi160ReturnValue);
        if (RETCODE_OK == apiReturnValue)
        {
            tempretVal = mappingEnumForGetFunctions((uint8_t) ACCELEROMETER_BMI160_POWERMODE_NORMAL, (uint8_t) ACCELEROMETER_BMI160_POWERMODE_SUSPEND, (uint8_t) *powermode, getmodeLookUpTable);
            if (GET_MAPPING_ERROR != tempretVal)
            {
                *powermode = (Accelerometer_Powermode_T) tempretVal;
            }
            else
            {
                apiReturnValue = (Retcode_T) RETCODE_NOT_SUPPORTED;
            }
        }
        break;
    default:
        apiReturnValue = (Retcode_T) RETCODE_INVALID_PARAM;
        break;
    }

    if ((RETCODE_OK != apiReturnValue) && (Retcode_getPackage(apiReturnValue) == PACKAGE_ID_DEFAULT))
    {
        apiReturnValue = RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) apiReturnValue);
    }

    return (apiReturnValue);
}

/* API documentation is in public interface header file 'BCDS_Accelerometer.h' */
Retcode_T Accelerometer_readXyzLsbValue(Accelerometer_HandlePtr_T handle, Accelerometer_XyzDataPtr_T accelData)
{


    struct bma2x2_accel_data bmaAccelData =
    {   INT16_C(0), INT16_C(0), INT16_C(0)};

    struct bmi160_accel_t bmiAccelData =
    {   INT16_C(0), INT16_C(0), INT16_C(0)};



    AxisRemap_Data_T readDataAccel =
        { INT32_C(0), INT32_C(0), INT32_C(0) };
    Retcode_T apiReturnValue = (Retcode_T) RETCODE_FAILURE;
    BMA2x2_RETURN_FUNCTION_TYPE libBma280ReturnValue = E_OUT_OF_RANGE;
    BMI160_RETURN_FUNCTION_TYPE libBmi160ReturnValue = E_BMI160_OUT_OF_RANGE;

    if ((NULL == handle) || ( NULL == handle->SensorPtr) || (NULL == accelData))
    {
        return (RETCODE(RETCODE_SEVERITY_FATAL, (uint32_t) RETCODE_INVALID_PARAM));
    }
    if (INIT_NOT_DONE == handle->SensorInformation.initializationStatus)
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) RETCODE_UNINITIALIZED));
    }

    switch (handle->SensorInformation.sensorID)
    {
    case ACCELEROMETER_BMA280:
        libBma280ReturnValue = bma2x2_read_accel_xyz(&bmaAccelData);
        apiReturnValue = bma2x2LibErrorMapping(libBma280ReturnValue);
        if (RETCODE_OK == apiReturnValue)
        {
            readDataAccel.x = bmaAccelData.x;
            readDataAccel.y = bmaAccelData.y;
            readDataAccel.z = bmaAccelData.z;
            apiReturnValue = Bma280Utils_remapAxis((Bma280Utils_InfoPtr_T) handle->SensorPtr, &readDataAccel);
        }
        if (RETCODE_OK == apiReturnValue)
        {
            accelData->xAxisData = readDataAccel.x;
            accelData->yAxisData = readDataAccel.y;
            accelData->zAxisData = readDataAccel.z;
        }
        break;
    case ACCELEROMETER_BMI160:



        libBmi160ReturnValue = bmi160_read_accel_xyz(&bmiAccelData);


        apiReturnValue = bmi160LibErrorMapping(libBmi160ReturnValue);
        if (RETCODE_OK == apiReturnValue)
        {
            readDataAccel.x = bmiAccelData.x;
            readDataAccel.y = bmiAccelData.y;
            readDataAccel.z = bmiAccelData.z;
            apiReturnValue = Bmi160Utils_remapAxis((Bmi160Utils_InfoPtr_T) handle->SensorPtr, &readDataAccel);
        }
        if (RETCODE_OK == apiReturnValue)
        {
            accelData->xAxisData = readDataAccel.x;
            accelData->yAxisData = readDataAccel.y;
            accelData->zAxisData = readDataAccel.z;
        }
        break;
    default:
        apiReturnValue = (Retcode_T) RETCODE_INVALID_PARAM;
        break;
    }

    if ((RETCODE_OK != apiReturnValue) && (Retcode_getPackage(apiReturnValue) == PACKAGE_ID_DEFAULT))
    {
        apiReturnValue = RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) apiReturnValue);
    }

    return (apiReturnValue);
}

/* API documentation is in public interface header file 'BCDS_Accelerometer.h' */
Retcode_T Accelerometer_readXyzGValue(Accelerometer_HandlePtr_T handle, Accelerometer_XyzDataPtr_T accelData)
{


    struct bma2x2_accel_data bmaAccelData =
    {   INT16_C(0), INT16_C(0), INT16_C(0)};

    struct bmi160_accel_t bmiAccelData =
    {   INT16_C(0), INT16_C(0), INT16_C(0)};



    AxisRemap_Data_T readDataAccel =
        { INT32_C(0), INT32_C(0), INT32_C(0) };

    Retcode_T apiReturnValue = (Retcode_T) RETCODE_FAILURE;
    BMA2x2_RETURN_FUNCTION_TYPE libBma280ReturnValue = E_OUT_OF_RANGE;
    BMI160_RETURN_FUNCTION_TYPE libBmi160ReturnValue = E_BMI160_OUT_OF_RANGE;
    int32_t bmaConvertionData = INT32_C(0);
    int64_t bmiConvertionData = INT64_C(0);

    if ((NULL == handle) || (NULL == accelData))
    {
        return (RETCODE(RETCODE_SEVERITY_FATAL, (uint32_t) RETCODE_INVALID_PARAM));
    }
    if (INIT_NOT_DONE == handle->SensorInformation.initializationStatus)
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) RETCODE_UNINITIALIZED));
    }

    switch (handle->SensorInformation.sensorID)
    {
    case ACCELEROMETER_BMA280:
        libBma280ReturnValue = bma2x2_read_accel_xyz(&bmaAccelData);
        apiReturnValue = bma2x2LibErrorMapping(libBma280ReturnValue);
        if (RETCODE_OK == apiReturnValue)
        {
            bmaConvertionData = (int32_t) (bmaAccelData.x * ACCEL_CONV_G_MG * bmaRangeValue);
            readDataAccel.x = (bmaConvertionData / BMA2X2_ONEBITRESOLUTION);

            bmaConvertionData = (int32_t) (bmaAccelData.y * ACCEL_CONV_G_MG * bmaRangeValue);
            readDataAccel.y = (bmaConvertionData / BMA2X2_ONEBITRESOLUTION);

            bmaConvertionData = (int32_t) (bmaAccelData.z * ACCEL_CONV_G_MG * bmaRangeValue);
            readDataAccel.z = (bmaConvertionData / BMA2X2_ONEBITRESOLUTION);

            apiReturnValue = Bma280Utils_remapAxis((Bma280Utils_InfoPtr_T) handle->SensorPtr, &readDataAccel);
        }
        if (RETCODE_OK == apiReturnValue)
        {
            accelData->xAxisData = readDataAccel.x;
            accelData->yAxisData = readDataAccel.y;
            accelData->zAxisData = readDataAccel.z;
        }
        break;
    case ACCELEROMETER_BMI160:



        libBmi160ReturnValue = bmi160_read_accel_xyz(&bmiAccelData);


        apiReturnValue = bmi160LibErrorMapping(libBmi160ReturnValue);
        if (RETCODE_OK == apiReturnValue)
        {
            bmiConvertionData = ((ACCEL_CONV_G_MG) * (int64_t) (bmiRangeValue) * (bmiAccelData.x));
            readDataAccel.x = (int32_t) (bmiConvertionData / BMI160_ONEBITRESOLUTION);

            bmiConvertionData = ((ACCEL_CONV_G_MG) * (int64_t) (bmiRangeValue) * (bmiAccelData.y));
            readDataAccel.y = (int32_t) (bmiConvertionData / BMI160_ONEBITRESOLUTION);

            bmiConvertionData = ((ACCEL_CONV_G_MG) * (int64_t) (bmiRangeValue) * (bmiAccelData.z));
            readDataAccel.z = (int32_t) (bmiConvertionData / BMI160_ONEBITRESOLUTION);

            apiReturnValue = Bmi160Utils_remapAxis((Bmi160Utils_InfoPtr_T) handle->SensorPtr, &readDataAccel);
        }
        if (RETCODE_OK == apiReturnValue)
        {
            accelData->xAxisData = readDataAccel.x;
            accelData->yAxisData = readDataAccel.y;
            accelData->zAxisData = readDataAccel.z;
        }
        break;
    default:
        apiReturnValue = (Retcode_T) RETCODE_INVALID_PARAM;
        break;
    }

    if ((RETCODE_OK != apiReturnValue) && (Retcode_getPackage(apiReturnValue) == PACKAGE_ID_DEFAULT))
    {
        apiReturnValue = RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) apiReturnValue);
    }

    return (apiReturnValue);
}

/* API documentation is in public interface header file 'BCDS_Accelerometer.h' */
Retcode_T Accelerometer_deInit(Accelerometer_HandlePtr_T handle)
{
    Retcode_T apiReturnValue = (Retcode_T) RETCODE_FAILURE;

    if (NULL == handle)
    {
        return (RETCODE(RETCODE_SEVERITY_FATAL, (uint32_t) RETCODE_INVALID_PARAM));
    }
    if (INIT_NOT_DONE == handle->SensorInformation.initializationStatus)
    {
        return (RETCODE_OK);
    }

    switch (handle->SensorInformation.sensorID)
    {
    case ACCELEROMETER_BMA280:

        apiReturnValue = Bma280Utils_uninitialize((Bma280Utils_InfoPtr_T) handle->SensorPtr);
        handle->SensorInformation.initializationStatus = INIT_NOT_DONE;
        break;
    case ACCELEROMETER_BMI160:
        apiReturnValue = Bmi160Utils_uninitialize((Bmi160Utils_InfoPtr_T) handle->SensorPtr);
        handle->SensorInformation.initializationStatus = INIT_NOT_DONE;
        break;
    default:
        apiReturnValue = (Retcode_T) RETCODE_INVALID_PARAM;
        break;
    }

    if ((RETCODE_OK != apiReturnValue) && (Retcode_getPackage(apiReturnValue) == PACKAGE_ID_DEFAULT))
    {
        apiReturnValue = RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) apiReturnValue);
    }

    return (apiReturnValue);
}

/* API documentation is in public interface header file 'BCDS_Accelerometer.h' */
Retcode_T Accelerometer_configInterrupt(Accelerometer_HandlePtr_T handle, Accelerometer_InterruptChannel_T channel, Accelerometer_InterruptType_T interruptType, void * InterruptTypeParameters)
{
    Retcode_T apiReturnValue = (Retcode_T) RETCODE_FAILURE;
    Bma280Utils_ConfigInterrupt_T utilsConfigInterrupt;

    if (NULL == handle || (channel >= ACCELEROMETER_INVALID_INTERRUPT_CHANNEL) || (interruptType >= ACCELEROMETER_INVALID_INTERRUPT)
            || NULL == handle->SensorPtr)
    {
        return (RETCODE(RETCODE_SEVERITY_FATAL, (uint32_t) RETCODE_INVALID_PARAM));
    }
    if (INIT_NOT_DONE == handle->SensorInformation.initializationStatus)
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) RETCODE_UNINITIALIZED));
    }

    utilsConfigInterrupt.interruptType = (Bma280Utils_IntrType_T) interruptType;
    utilsConfigInterrupt.interruptChannel = (Bma280Utils_IntrChannel_T) channel;
    utilsConfigInterrupt.configInterrupt = InterruptTypeParameters;

    switch (handle->SensorInformation.sensorID)
    {
    case ACCELEROMETER_BMI160:
        apiReturnValue = (Retcode_T) RETCODE_NOT_SUPPORTED;
        break;
    case ACCELEROMETER_BMA280:
        switch (interruptType)
        {
        case ACCELEROMETER_BMA280_SLOPE_INTERRUPT:
            {
            Accelerometer_ConfigSlopeIntrPtr_T slopeParameterPtr = (Accelerometer_ConfigSlopeIntrPtr_T) InterruptTypeParameters;
            if ((NULL != InterruptTypeParameters) && (slopeParameterPtr->slopeEnableX <= UINT8_C(1)) && (slopeParameterPtr->slopeEnableY <= UINT8_C(1))
                    && (slopeParameterPtr->slopeEnableZ <= UINT8_C(1)) && (slopeParameterPtr->slopeDuration < ACCELEROMETER_INVALID_SLOPE_DURATION))
            {
                apiReturnValue = Bma280Utils_configInterrupt((Bma280Utils_InfoPtr_T) handle->SensorPtr, &utilsConfigInterrupt);
            }
            else
            {
                apiReturnValue = (RETCODE(RETCODE_SEVERITY_FATAL, (uint32_t) RETCODE_INVALID_PARAM));
            }
        }
            break;
        case ACCELEROMETER_BMA280_NEW_DATA_INTERRUPT:
            {
            apiReturnValue = Bma280Utils_configInterrupt((Bma280Utils_InfoPtr_T) handle->SensorPtr, &utilsConfigInterrupt);
            break;
        }
        default:
            apiReturnValue = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_INVALID_PARAM);
            break;
        }
        break;
    default:
        apiReturnValue = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_INVALID_PARAM);
        break;
    }

    if ((RETCODE_OK != apiReturnValue) && (Retcode_getPackage(apiReturnValue) == PACKAGE_ID_DEFAULT))
    {
        apiReturnValue = RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) apiReturnValue);
    }

    return (apiReturnValue);
}

/* API documentation is in public interface header file 'BCDS_Accelerometer.h' */
Retcode_T Accelerometer_disableInterrupt(Accelerometer_HandlePtr_T handle, Accelerometer_InterruptChannel_T channel, Accelerometer_InterruptType_T interruptType)
{
    Retcode_T apiReturnValue = (Retcode_T) RETCODE_FAILURE;

    if ((NULL == handle) || (channel >= ACCELEROMETER_INVALID_INTERRUPT_CHANNEL) || (interruptType >= ACCELEROMETER_INVALID_INTERRUPT) || (NULL == handle->SensorPtr))
    {
        return (RETCODE(RETCODE_SEVERITY_FATAL, (uint32_t) RETCODE_INVALID_PARAM));
    }
    if (INIT_NOT_DONE == handle->SensorInformation.initializationStatus)
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) RETCODE_UNINITIALIZED));
    }

    switch (handle->SensorInformation.sensorID)
    {
    case ACCELEROMETER_BMA280:
        {
            apiReturnValue = Bma280Utils_disableInterrupt((Bma280Utils_InfoPtr_T) handle->SensorPtr, (Bma280Utils_IntrType_T) interruptType, (Bma280Utils_IntrChannel_T) channel);
            break;
        }
    case ACCELEROMETER_BMI160:
        {
            apiReturnValue = (Retcode_T) RETCODE_NOT_SUPPORTED;
            break;
        }
    default:
        apiReturnValue = (Retcode_T) RETCODE_INVALID_PARAM;
        break;
    }

    if ((RETCODE_OK != apiReturnValue) && (Retcode_getPackage(apiReturnValue) == PACKAGE_ID_DEFAULT))
    {
        apiReturnValue = RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) apiReturnValue);
    }

    return (apiReturnValue);

}

/* API documentation is in public interface header file 'BCDS_Accelerometer.h' */
Retcode_T Accelerometer_regRealTimeCallback(Accelerometer_HandlePtr_T handle, Accelerometer_InterruptChannel_T channel, accelRealTimeCallback realTimeCallback)
{
    Retcode_T apiReturnValue = (Retcode_T) RETCODE_FAILURE;

    if ((NULL == handle) || (NULL == handle->SensorPtr) || (NULL == realTimeCallback) || (channel >= ACCELEROMETER_INVALID_INTERRUPT_CHANNEL))
    {
        return (RETCODE(RETCODE_SEVERITY_FATAL, (uint32_t) RETCODE_INVALID_PARAM));
    }
    if (INIT_NOT_DONE == handle->SensorInformation.initializationStatus)
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) RETCODE_UNINITIALIZED));
    }

    switch (handle->SensorInformation.sensorID)
    {
    case ACCELEROMETER_BMA280:
        {
        Bma280Utils_InfoPtr_T bma280UtilsInstance = (Bma280Utils_InfoPtr_T) handle->SensorPtr;
        if (channel == ACCELEROMETER_BMA280_INTERRUPT_CHANNEL1)
        {
            bma280UtilsInstance->interruptPin1.enable = UINT8_C(1);
            bma280UtilsInstance->interruptPin1.callBack = (Gpio_intrCallback) realTimeCallback;
            apiReturnValue = (Retcode_T) RETCODE_OK;
        }
        else
        {
            bma280UtilsInstance->interruptPin2.enable = UINT8_C(1);
            bma280UtilsInstance->interruptPin2.callBack = (Gpio_intrCallback) realTimeCallback;
            apiReturnValue = (Retcode_T) RETCODE_OK;
        }
        break;
    }
    case ACCELEROMETER_BMI160:
        {
            apiReturnValue = (Retcode_T) RETCODE_NOT_SUPPORTED;
            break;
        }
    default:
        apiReturnValue = (Retcode_T) RETCODE_INVALID_PARAM;
        break;
    }

    if ((RETCODE_OK != apiReturnValue) && (Retcode_getPackage(apiReturnValue) == PACKAGE_ID_DEFAULT))
    {
        apiReturnValue = RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) apiReturnValue);
    }

    return (apiReturnValue);
}

/* API documentation is in public interface header file 'BCDS_Accelerometer.h' */
Retcode_T Accelerometer_regDeferredCallback(Accelerometer_HandlePtr_T handle, Accelerometer_InterruptChannel_T channel, accelDeferredTimeCallback deferredCallback)
{
    Retcode_T apiReturnValue = (Retcode_T) RETCODE_FAILURE;

    if ((NULL == handle) || (channel >= ACCELEROMETER_INVALID_INTERRUPT_CHANNEL) || (NULL == handle->SensorPtr) || (NULL == deferredCallback))
    {
        return (RETCODE(RETCODE_SEVERITY_FATAL, (uint32_t) RETCODE_INVALID_PARAM));
    }
    if (INIT_NOT_DONE == handle->SensorInformation.initializationStatus)
    {
        return (RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) RETCODE_UNINITIALIZED));
    }

    switch (handle->SensorInformation.sensorID)
    {
    case ACCELEROMETER_BMA280:
        {
        Bma280Utils_InfoPtr_T bma280UtilsInstance = (Bma280Utils_InfoPtr_T) handle->SensorPtr;
        if (channel == ACCELEROMETER_BMA280_INTERRUPT_CHANNEL1)
        {
            bma280UtilsInstance->interruptPin1.enable = UINT8_C(1);
            bmaDeferredCallbackChannel1Ptr =  deferredCallback;
            bma280UtilsInstance->interruptPin1.callBack = (Gpio_intrCallback) bmaChannel1IsrCallback;
            apiReturnValue = RETCODE_OK;
        }
        else
        {
            bma280UtilsInstance->interruptPin2.enable = UINT8_C(1);
            bmaDeferredCallbackChannel2Ptr =  deferredCallback;
            bma280UtilsInstance->interruptPin2.callBack = (Gpio_intrCallback) bmaChannel2IsrCallback;
            apiReturnValue = RETCODE_OK;
        }
        break;
    }
    case ACCELEROMETER_BMI160:
        {
            apiReturnValue = (Retcode_T) RETCODE_NOT_SUPPORTED;
            break;
        }
    default:
        apiReturnValue = (Retcode_T) RETCODE_INVALID_PARAM;
        break;
    }

    if ((RETCODE_OK != apiReturnValue) && (Retcode_getPackage(apiReturnValue) == PACKAGE_ID_DEFAULT))
    {
        apiReturnValue = RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t) apiReturnValue);
    }

    return (apiReturnValue);
}
